package com.quanyan.stadium.service.commonComponent.impl;

import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.quanyan.api.APIRequest;
import com.quanyan.api.APIResponse;
import com.quanyan.common.Plugin.Page;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.exception.BizException;
import com.quanyan.common.utils.StringUtil;
import com.quanyan.orderpay.request.ReqOrderInfo;
import com.quanyan.orderpay.response.RespOrderInfo;
import com.quanyan.orderpay.service.OrderPayService;
import com.quanyan.stadium.api.resp.RespUserCategoryVo;
import com.quanyan.stadium.biz.BizGameSystemDao;
import com.quanyan.stadium.biz.BizSportCardDao;
import com.quanyan.stadium.constants.GameConstants;
import com.quanyan.stadium.entity.TbGameEvent;
import com.quanyan.stadium.entity.TbGameEventExample;
import com.quanyan.stadium.entity.TbGameEventTeam;
import com.quanyan.stadium.entity.TbGameOrder;
import com.quanyan.stadium.entity.TbGameOrderExample;
import com.quanyan.stadium.entity.TbPoints;
import com.quanyan.stadium.entity.vo.GameEvent;
import com.quanyan.stadium.entity.vo.GameSystem;
import com.quanyan.stadium.entity.vo.MultiMedia;
import com.quanyan.stadium.entity.vo.PlaceInfo;
import com.quanyan.stadium.mapper.TbGameEventMapper;
import com.quanyan.stadium.mapper.TbGameEventTeamMapper;
import com.quanyan.stadium.mapper.TbGameOrderMapper;
import com.quanyan.stadium.mapper.TbUserGameCollectMapper;
import com.quanyan.stadium.mapper.VStadiumUserDefinedMapper;
import com.quanyan.stadium.service.PointsService;
import com.quanyan.stadium.service.SportCardService;
import com.quanyan.stadium.service.commonComponent.BaseService;
import com.quanyan.stadium.service.commonComponent.OfficialGameCache;
import com.quanyan.stadium.transfer.GameConfigTransfer;
import com.quanyan.statium.api.req.ReqLastGameEvent;
import com.quanyan.statium.api.resp.GameClubMoney;
import com.quanyan.statium.api.resp.GameEventSummary;
import com.quanyan.statium.api.resp.ResGameEvent;
import com.quanyan.statium.api.resp.ResPlaceGameEventMsg;
import com.quanyan.statium.api.resp.ResPoints;
import com.quanyan.statium.api.resp.ResUserGameEvent;
import com.quanyan.statium.api.resp.RespGameDetail;
import com.quanyan.statium.api.resp.RespGameOrder;
import com.quanyan.statium.api.resp.RespUserCategory;
import com.quanyan.statium.api.resp.RespUserLastGameEvent;
import com.quanyan.statium.service.StadiumOpenService;
import com.quanyan.user.response.RespUserInfoBase;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xiaoxiao
 * @date 16/4/11-14:42
 *
 *
 * 描述:该service为外部提供相关的dubbo服务
 */

@Service("stadiumOpenService")
public class StadiumOpenServiceImpl implements StadiumOpenService {
    private final static Logger logger = LoggerFactory.getLogger(StadiumOpenServiceImpl.class);

    @Autowired
    private BizGameSystemDao bizGameSystemDao;

    @Autowired
    private TbGameEventMapper tbGameEventMapper;

    @Autowired
    private BizSportCardDao bizSportCardDao;

    @Autowired
    private BaseService baseService;

    @Autowired
    PointsService pointsService;

    @Autowired
    private TbGameOrderMapper orderMapper;

    @Autowired
    private OfficialGameCache officialGameCache;

    @Autowired
    private SportCardService sportCardService;

    @Autowired
    private OrderPayService orderPayService;

    @Autowired
    private GameConfigTransfer gameEventTransfer;

    @Autowired
    TbGameEventTeamMapper tbGameEventTeamMapper;

    @Autowired
    TbUserGameCollectMapper tbUserGameCollectMapper;

    @Autowired
    VStadiumUserDefinedMapper vStadiumUserDefinedMapper;

    public final static Map<Integer, String> globalMap = new HashMap();
    static {
        globalMap.put(1, "http://quncao.b0.upaiyun.com/club/activity/poster/basketball/basketball1.png");
        globalMap.put(2, "http://quncao.b0.upaiyun.com/club/activity/poster/badminton/badminton1.png");
        globalMap.put(3, "http://quncao.b0.upaiyun.com/club/activity/poster/football/football1.png");
        globalMap.put(4, "http://quncao.b0.upaiyun.com/club/activity/poster/tennis/tennis1.png");
    }

    @Override
    public ResGameEvent getResGameEventByClubId(Integer clubId) {
        List<TbGameEvent> tbGameEvents = bizGameSystemDao.selectTbGameEventByClubId(clubId, 0, 1);

        if (null != tbGameEvents && tbGameEvents.size() > 0) {
            TbGameEvent tbGameEvent = tbGameEvents.get(0);
            ResGameEvent resGameEvent = new ResGameEvent();
            try {
                BeanUtils.copyProperties(tbGameEvent, resGameEvent);
                List<Integer> placeIds = new ArrayList<>();
                placeIds.add(tbGameEvent.getPlaceId());
                Map<Integer, PlaceInfo>  placeMap = baseService.queryPlaceInfoMsgList(placeIds);
                if (null!=placeMap && placeMap.size() == 1) {
                    PlaceInfo placeInfo = placeMap.get(tbGameEvent.getPlaceId());
                    resGameEvent.setCityName(placeInfo.getCityName());
                    resGameEvent.setDistrictName(placeInfo.getDistrictName());
                    resGameEvent.setPlaceName(placeInfo.getName());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            resGameEvent.setImageUrl(globalMap.get(tbGameEvent.getCategoryId()));
            return resGameEvent;
        }

        return null;
    }

    @Override
    public int countGameEventSigningByClubId(Integer clubId) {
        return bizGameSystemDao.countGameEventSigningByClubId(clubId);
    }

    @Override
    public int countGameEventPlayingByClubId(Integer clubId) {
        return 0;
    }

    @Override
    public ResPlaceGameEventMsg getGameEventListByPlaceIdAndCategoryId(Integer uid, Integer categoryId, Integer placeId) {
        List<TbGameEvent> tbGameEventList = bizGameSystemDao.selectNotSignStartTbGameEventByPlaceIdAndCategoryId(categoryId, placeId);
        List<Integer> userClubIds = baseService.queryMyClubListByCategoryId(uid, categoryId);   //该栏目下所有俱乐部
        List<TbGameEvent> clubList = bizGameSystemDao.selectTbGameEventByClubId(userClubIds);       //获取这些俱乐部发布的赛事
        ResPlaceGameEventMsg resPlaceGameEventMsg = new ResPlaceGameEventMsg();
        if (null ==tbGameEventList || tbGameEventList.size()<1) {
            resPlaceGameEventMsg.setGameEventNum(0);
            resPlaceGameEventMsg.setRecommendGameEvent(null);
        }else {
            resPlaceGameEventMsg.setGameEventNum(tbGameEventList.size());
            TbGameEvent sourceGameEvent = new TbGameEvent();
            for (TbGameEvent tbGameEvent:tbGameEventList) {
                if (tbGameEvent.getIsVisible().intValue() == GameConstants.IS_DELETE.intValue() ||
                        clubList.contains(tbGameEvent)) {
                    sourceGameEvent = tbGameEvent;
                    break;
                }
            }
            if (null == sourceGameEvent || null == sourceGameEvent.getId()) {
                sourceGameEvent =  tbGameEventList.get(0);
            }

            //推荐最新的一个, 按该逻辑进行处理
            List<TbGameEventTeam> tbGameEventTeamList = bizGameSystemDao.selectTbGameEventTeamByGameEventId(sourceGameEvent.getId(), GameConstants.IS_NOT_DELETE);
            ResUserGameEvent resUserGameEvent = new ResUserGameEvent();
            resUserGameEvent.setId(sourceGameEvent.getId());
            resUserGameEvent.setName(sourceGameEvent.getName());
            resUserGameEvent.setStartTime(sourceGameEvent.getStartTime().getTime());
            resUserGameEvent.setEndTime(sourceGameEvent.getEndTime().getTime());
            if (tbGameEventTeamList!=null && tbGameEventTeamList.size() > 0) {
                resUserGameEvent.setIsJoin((byte) 0);
                List<Integer> uIds = new ArrayList<>();
                List<Integer> clubIds = new ArrayList<>();
                for (TbGameEventTeam team : tbGameEventTeamList) {
                    uIds.add(team.getUid());
                    clubIds.add(team.getClubId());
                }
                resUserGameEvent.setType(sourceGameEvent.getGameTeamType());
                if (sourceGameEvent.getGameTeamType().equals(GameConstants.TEAM_TYPE_CLUB)) {
                    resUserGameEvent.setSignClubIds(clubIds);
                }else if (sourceGameEvent.getGameTeamType().equals(GameConstants.TEAM_TYPE_PERSON)) {
                    resUserGameEvent.setSignUids(uIds);
                }else {
                    ;
                }
            }else {
                resUserGameEvent.setIsJoin((byte) 0);
                resUserGameEvent.setSignUids(null);
            }

            resPlaceGameEventMsg.setRecommendGameEvent(resUserGameEvent);
        }
        return resPlaceGameEventMsg;
    }

    @Override
    public List<RespUserCategory> getUserCategoryList(Integer userId) {
        List<RespUserCategory> respUserCategoryList = new ArrayList<>();
        if (null != userId){
            List<RespUserCategoryVo> respUserCategoryVoList = bizSportCardDao.getUserCategoryList(userId);
            if (null != respUserCategoryVoList && respUserCategoryVoList.size() >0){
                for (RespUserCategoryVo vo : respUserCategoryVoList){
                    RespUserCategory userCategory = new RespUserCategory();
                    BeanUtils.copyProperties(vo,userCategory);

                    //运动名片是否设置
                    Boolean isSetted =  sportCardService.isSetted(userId, vo.getGameCategoryId());
                    userCategory.setIsSetted(isSetted);
                    respUserCategoryList.add(userCategory);
                }
            }else{
                sportCardService.initSportCard(userId);
                List<RespUserCategoryVo> categoryList = bizSportCardDao.getUserCategoryList(userId);
                if (null != categoryList && categoryList.size() >0){
                    for (RespUserCategoryVo vo : categoryList){
                        RespUserCategory userCategory = new RespUserCategory();
                        BeanUtils.copyProperties(vo,userCategory);

                        //运动名片是否设置
                        Boolean isSetted =  sportCardService.isSetted(userId, vo.getGameCategoryId());
                        userCategory.setIsSetted(isSetted);
                        respUserCategoryList.add(userCategory);
                    }
                }
            }
        }
        return respUserCategoryList;
    }

    @Override
    public List<ResPoints> batchQueryUserCategoryPoints(List<Integer> uidList, Integer categoryId) {
        List<ResPoints> resPointsList = Collections.emptyList();
        List<TbPoints> tbPointsList = pointsService.queryPointsByCategoryIdAndUserIds(uidList, categoryId);
        ResPoints resPoints = null;
        try {
            resPointsList = new ArrayList<>();
            for(TbPoints tbPoints : tbPointsList) {
                resPoints = new ResPoints();
                BeanUtils.copyProperties(tbPoints, resPoints);
                resPointsList.add(resPoints);
            }
        }catch (Exception e) {
            logger.error("batchQueryUserCategoryPoints is failed. e:", e);
        }

        return resPointsList;
    }


    @Override
    public PageObj<List<GameEventSummary>> getLastGameEventsByPlaceIdAndCategoryId(ReqLastGameEvent reqLastGameEvent) {
        List<GameEventSummary> gameEvents = new ArrayList<>();
        TbGameEventExample tbGameEventExample = new TbGameEventExample();
        TbGameEventExample.Criteria criteria = tbGameEventExample.createCriteria();
        criteria.andPlaceIdEqualTo(reqLastGameEvent.getPlaceId());
        criteria.andCategoryIdEqualTo(reqLastGameEvent.getCategoryId());

        //获取未开始的比赛
        Date currentTime = new Date();

        criteria.andStartTimeGreaterThan(currentTime);
        int total = tbGameEventMapper.countByExample(tbGameEventExample);
        if (total == 0){
            return PageObj.create(total,reqLastGameEvent.getPageNum(),reqLastGameEvent.getPageCount(),gameEvents);
        }

        //按比赛开始时间倒序
        tbGameEventExample.setOrderByClause(" start_time DESC");
        tbGameEventExample.setPage(new Page(reqLastGameEvent.getPageCount() * (reqLastGameEvent.getPageNum()), reqLastGameEvent.getPageCount()));
        List<TbGameEvent> tbGameEventList = tbGameEventMapper.selectByExample(tbGameEventExample);
        if (null != tbGameEventList && tbGameEventList.size() > 0) {
            for (TbGameEvent tbGameEvent : tbGameEventList) {
                GameEventSummary gameEventSummary = new GameEventSummary();
                org.springframework.beans.BeanUtils.copyProperties(tbGameEvent, gameEventSummary);
                gameEventSummary.setStartTime(tbGameEvent.getStartTime().getTime());
                gameEventSummary.setEndTime(tbGameEvent.getEndTime().getTime());
                gameEventSummary.setGameEventType(tbGameEvent.getGameEventType());
                //赛事图片
                Gson gson = new Gson();
                try{
                    MultiMedia multiMedia = gson.fromJson(tbGameEvent.getMultiMedia(), MultiMedia.class);
                    gameEventSummary.setImageUrl(multiMedia.getImage().getImageUrl());
                }catch (Exception e) {
                    e.printStackTrace();
                }
                //赛制
                GameSystem gameSystem =  gameEventTransfer.getGameSystemById(tbGameEvent.getGameSystemType().intValue());
                com.quanyan.statium.api.req.GameSystem gs = new com.quanyan.statium.api.req.GameSystem();
                if (null != gameSystem){
                    org.springframework.beans.BeanUtils.copyProperties(gameSystem,gs);
                }
                gameEventSummary.setGameSystem(gs);
                gameEvents.add(gameEventSummary);
            }
        }
        return PageObj.create(total,reqLastGameEvent.getPageNum(),reqLastGameEvent.getPageCount(),gameEvents);
    }

    @Override
    public RespGameDetail getGameDetailByGameId(Integer gameId) {
        RespGameDetail gameDetail = new RespGameDetail();
        TbGameEvent gameEvent = tbGameEventMapper.selectByPrimaryKey(gameId);
        if (null != gameEvent) {
            try {
                BeanUtils.copyProperties(gameEvent,gameDetail);
            } catch (Exception e) {
                logger.error("通过比赛id={}查询比赛详情失败！", gameId);
            }
        }
        return gameDetail;
    }

    @Override
    public GameClubMoney getGameClubMoney(Integer gameId){
        BigDecimal totalMoney = BigDecimal.valueOf(0d);
        BigDecimal all = BigDecimal.valueOf(0d);
        double egg = 0;
        GameClubMoney gameClubMoney = new GameClubMoney();
        logger.info("俱乐部结算开始：gameid = {}",gameId);
        TbGameEvent gameEvent = tbGameEventMapper.selectByPrimaryKey(gameId);
        if(null == gameEvent){
            logger.error("通过比赛id查询比赛详情失败！,停止俱乐部结算");
            return null;
        }else{
            gameClubMoney.setCreateDate(gameEvent.getCreateTime().getTime());
            gameClubMoney.setGameId(gameId);
            gameClubMoney.setGameName(gameEvent.getName());
            RespUserInfoBase user = baseService.queryUserMsg(gameEvent.getUid());
            if(user != null){
                gameClubMoney.setUid(user.getUid());
                gameClubMoney.setUserName(user.getNickName());
                gameClubMoney.setUserLogo(user.getIcon());
            }
            TbGameOrderExample example = new TbGameOrderExample();
            TbGameOrderExample.Criteria criteria = example.createCriteria();
            criteria.andGameEventIdEqualTo(gameId);
            criteria.andIsCloseEqualTo(GameConstants.ORDER_IS_CLOST_YES);
            criteria.andOrderStatusEqualTo(GameConstants.SUCCESS_ORDER);
            criteria.andPayWaitEqualTo(GameConstants.SUCCESS_PAY);
            List<TbGameOrder> orders = orderMapper.selectByExample(example);
            if(!CollectionUtils.isEmpty(orders)){
                gameClubMoney.setUserCount(orders.size());
                for(TbGameOrder order :orders){
                    if(order.getPayAmount() != null){
                        totalMoney = totalMoney.add(order.getPayAmount());
                    }
                    if(order.getAccumulate() != null){
                        egg = egg + order.getAccumulate();
                    }
                }
            }
            double eggMoney = egg / 10;
            all = totalMoney.add(BigDecimal.valueOf(eggMoney));
            gameClubMoney.setMoney(all);
        }
        return gameClubMoney;
    }

    @Override
    public List<RespGameOrder> queryOrderNoByGameId(Integer gameId) {
        List<RespGameOrder> respGameOrders = Lists.newArrayList();
        TbGameOrderExample example = new TbGameOrderExample();
        TbGameOrderExample.Criteria criteria = example.createCriteria();
        criteria.andGameEventIdEqualTo(gameId);
        criteria.andPayWaitEqualTo(GameConstants.SUCCESS_PAY);
        criteria.andOrderStatusEqualTo(GameConstants.SUCCESS_ORDER);
        criteria.andIsCloseEqualTo(GameConstants.ORDER_IS_CLOST_YES);
        List<TbGameOrder> gameOrders = orderMapper.selectByExample(example);
        if(gameOrders != null && gameOrders.size() > 0){
            for(TbGameOrder gameOrder : gameOrders){
                RespGameOrder respGameOrder = new RespGameOrder();
                respGameOrder.setAccumulate(gameOrder.getAccumulate());
                try {
                    if (!StringUtil.isBlankOrNull(gameOrder.getGameOrderNo())) {
                        //respGameOrder.setGameOrderNo();
                        ReqOrderInfo info = new ReqOrderInfo();
                        info.setUid(gameOrder.getUid());
                        info.setOutTradeNo(gameOrder.getTradeOrderNo());
                        info.setOrderNo(gameOrder.getGameOrderNo());
                        APIRequest<ReqOrderInfo> request = new APIRequest<ReqOrderInfo>();
                        request.setData(info);
                        APIResponse<RespOrderInfo> temp = orderPayService.orderQuery(request);
                        if (temp.isRet()) {
                            respGameOrder.setTradeOrderNo(temp.getData().getPayTsn());
                        }
                    }
                } catch (Exception e) {
                    logger.debug("赛事id获取赛事订单信息:{}", e);
                }
                respGameOrder.setGameOrderNo(gameOrder.getTradeOrderNo());
                respGameOrder.setPayAmount(gameOrder.getPayAmount().doubleValue());
                respGameOrder.setPayTime(gameOrder.getPayTime());
                respGameOrder.setPayType(gameOrder.getPayType() == null ? 0 :gameOrder.getPayType().intValue());
                respGameOrder.setPrice(gameOrder.getOrderAmount().doubleValue());
                //respGameOrder.setTradeOrderNo(gameOrder.getTradeOrderNo());
                respGameOrder.setGameName(gameOrder.getGameName());
                respGameOrders.add(respGameOrder);
            }
        }
        Gson gson = new Gson();
        logger.info("赛事id获取赛事订单信息返回值"+gson.toJson(respGameOrders));
        return respGameOrders;
    }

    @Override
    public List<ResGameEvent> getResGameEventsByClubId(Integer clubId, int num) throws InvocationTargetException, IllegalAccessException {
        List<TbGameEvent> tbGameEvents = bizGameSystemDao.selectTbGameEventByClubId(clubId, 0, num);
        if (null != tbGameEvents && tbGameEvents.size() > 0) {
            List<ResGameEvent> resGameEvents = new ArrayList<>();
            for (TbGameEvent tbGameEvent : tbGameEvents) {

                GameEvent gameEvent = officialGameCache.getGameEvent(tbGameEvent.getId());
                ResGameEvent resGameEvent = new ResGameEvent();
                try {
                    BeanUtils.copyProperties(gameEvent, resGameEvent);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                resGameEvents.add(resGameEvent);
            }
            return resGameEvents;
        }
        return null;
    }

    @Override
    public RespUserLastGameEvent getUserLastGameEvent(Integer uid) {
        RespUserLastGameEvent respUserLastGameEvent = new RespUserLastGameEvent();
        if(null == uid || uid == 0){
            throw new BizException("找不到该用户");
        }
        TbGameEvent  gameEvent = vStadiumUserDefinedMapper.getUserLastGameEvent(uid);
        if(null != gameEvent){
            respUserLastGameEvent.setGameStartTime(gameEvent.getStartTime());
            respUserLastGameEvent.setAddress(gameEvent.getAddress());
            respUserLastGameEvent.setGameEventId(gameEvent.getId());
            respUserLastGameEvent.setCategoryId(gameEvent.getCategoryId());
        }
        respUserLastGameEvent.setAttendCount(this.getUserGameEventCount(uid));
        return respUserLastGameEvent;
    }

    @Override
    public int getUserGameEventCount(Integer uid) {
//        TbGameEventTeamExample example = new TbGameEventTeamExample();
//        TbGameEventTeamExample.Criteria criteria = example.createCriteria();
//        criteria.andUidEqualTo(uid);
//        criteria.andIsDeleteEqualTo(GameConstants.IS_NOT_DELETE);
//        List<TbGameEventTeam> gameEventTeams = tbGameEventTeamMapper.selectByExample(example);
        return vStadiumUserDefinedMapper.getUserGameEventCount(uid);
    }


}
